home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / GLUT-3.7 / PROGS / INVENTOR / glutduck.c++ < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-12  |  6.7 KB  |  291 lines

  1.  
  2. /* Copyright (c) Mark J. Kilgard, 1994. */
  3.  
  4. /* This program is freely distributable without licensing fees 
  5.    and is provided without guarantee or warrantee expressed or 
  6.    implied. This program is -not- in the public domain. */
  7.  
  8. /*
  9.  * Copyright (c) 1991-94 Silicon Graphics, Inc.
  10.  *
  11.  * Permission to use, copy, modify, distribute, and sell this software and
  12.  * its documentation for any purpose is hereby granted without fee, provided
  13.  * that the name of Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Silicon Graphics.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
  20.  *
  21.  * IN NO EVENT SHALL SILICON GRAPHICS BE LIABLE FOR ANY SPECIAL, INCIDENTAL,
  22.  * INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSOEVER
  23.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER OR NOT ADVISED OF THE
  24.  * POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF LIABILITY, ARISING OUT OF OR IN
  25.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  26.  */
  27.  
  28. /* Based on an example from the Inventor Mentor chapter 13, example 5. */
  29.  
  30. #include <stdio.h>
  31. #include <unistd.h>
  32. #include <math.h>
  33.  
  34. #include <GL/gl.h>
  35. #include <GL/glu.h>
  36. #include <GL/glut.h>
  37.  
  38. #include <Inventor/SoDB.h>
  39. #include <Inventor/SoInput.h>
  40. #include <Inventor/SbViewportRegion.h>
  41. #include <Inventor/nodes/SoSeparator.h>
  42. #include <Inventor/actions/SoGLRenderAction.h>
  43. #include <Inventor/nodes/SoCylinder.h>
  44. #include <Inventor/nodes/SoDirectionalLight.h>
  45. #include <Inventor/nodes/SoEventCallback.h>
  46. #include <Inventor/nodes/SoMaterial.h>
  47. #include <Inventor/nodes/SoPerspectiveCamera.h>
  48. #include <Inventor/nodes/SoRotationXYZ.h>
  49. #include <Inventor/nodes/SoTransform.h>
  50. #include <Inventor/nodes/SoTranslation.h>
  51.  
  52. /* Some <math.h> files do not define M_PI... */
  53. #ifndef M_PI
  54. #define M_PI 3.14159265358979323846
  55. #endif
  56.  
  57. int W = 300, H = 300;
  58. int spinning = 0;
  59. GLubyte *image = NULL;
  60. SoSeparator *root;
  61. SoRotationXYZ *duckRotXYZ;
  62. float angle = 0.0;
  63. int moving  = 0;
  64. int begin;
  65.  
  66. void
  67. reshape(int w, int h)
  68. {
  69.   glViewport(0, 0, w, h);
  70.   W = w;
  71.   H = h;
  72.   if (image)
  73.     free(image);
  74.   image = (GLubyte *) malloc(W * H * 3);
  75. }
  76.  
  77. void
  78. renderScene(void)
  79. {
  80.   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  81.   SbViewportRegion myViewport(W, H);
  82.   SoGLRenderAction myRenderAction(myViewport);
  83.   myRenderAction.apply(root);
  84. }
  85.  
  86. void
  87. redraw(void)
  88. {
  89.   renderScene();
  90.   glutSwapBuffers();
  91. }
  92.  
  93. int
  94. duckScene(void)
  95. {
  96.    root = new SoSeparator;
  97.    root->ref();
  98.  
  99.    // Add a camera and light
  100.    SoPerspectiveCamera *myCamera = new SoPerspectiveCamera;
  101.    myCamera->position.setValue(0., -4., 8.0);
  102.    myCamera->heightAngle = M_PI/2.5; 
  103.    myCamera->nearDistance = 1.0;
  104.    myCamera->farDistance = 15.0;
  105.    root->addChild(myCamera);
  106.    root->addChild(new SoDirectionalLight);
  107.  
  108.    // Rotate scene slightly to get better view
  109.    SoRotationXYZ *globalRotXYZ = new SoRotationXYZ;
  110.    globalRotXYZ->axis = SoRotationXYZ::X;
  111.    globalRotXYZ->angle = M_PI/9;
  112.    root->addChild(globalRotXYZ);
  113.  
  114.    // Pond group
  115.    SoSeparator *pond = new SoSeparator; 
  116.    root->addChild(pond);
  117.    SoMaterial *cylMaterial = new SoMaterial;
  118.    cylMaterial->diffuseColor.setValue(0., 0.3, 0.8);
  119.    pond->addChild(cylMaterial);
  120.    SoTranslation *cylTranslation = new SoTranslation;
  121.    cylTranslation->translation.setValue(0., -6.725, 0.);
  122.    pond->addChild(cylTranslation);
  123.    SoCylinder *myCylinder = new SoCylinder;
  124.    myCylinder->radius.setValue(4.0);
  125.    myCylinder->height.setValue(0.5);
  126.    pond->addChild(myCylinder);
  127.  
  128.    // Duck group
  129.    SoSeparator *duck = new SoSeparator;
  130.    root->addChild(duck);
  131.  
  132.    // Read the duck object from a file and add to the group
  133.    SoInput myInput;
  134.    if (!myInput.openFile("duck.iv"))  {
  135.       if (!myInput.openFile("/usr/share/src/Inventor/examples/data/duck.iv")) {
  136.         return 1;
  137.       }
  138.    }
  139.    SoSeparator *duckObject = SoDB::readAll(&myInput);
  140.    if (duckObject == NULL) return 1;
  141.  
  142.    // Set up the duck transformations
  143.    duckRotXYZ = new SoRotationXYZ;
  144.    duck->addChild(duckRotXYZ);
  145.    duckRotXYZ->angle = angle;
  146.    duckRotXYZ->axis = SoRotationXYZ::Y;  // rotate about Y axis
  147.    SoTransform *initialTransform = new SoTransform;
  148.    initialTransform->translation.setValue(0., 0., 3.);
  149.    initialTransform->scaleFactor.setValue(6., 6., 6.);
  150.    duck->addChild(initialTransform);
  151.    duck->addChild(duckObject);
  152.  
  153.    return 0;
  154. }
  155.  
  156. void
  157. updateModels(void)
  158. {
  159.   duckRotXYZ->angle = angle;
  160.   glutPostRedisplay();
  161. }
  162.  
  163. void
  164. animate(void)
  165. {
  166.   angle += 0.1;
  167.   updateModels();
  168. }
  169.  
  170. void
  171. setAnimation(int enable)
  172. {
  173.   if(enable) {
  174.     spinning = 1;
  175.     glutIdleFunc(animate);
  176.   } else {
  177.     spinning = 0;
  178.     glutIdleFunc(NULL);
  179.     glutPostRedisplay();
  180.   }
  181. }
  182.  
  183. /* ARGSUSED */
  184. void
  185. keyboard(unsigned char ch, int x, int y)
  186. {
  187.   if(ch == ' ') {
  188.     setAnimation(0);
  189.     animate();
  190.   }
  191. }
  192.  
  193. void
  194. menuSelect(int item)
  195. {
  196.    switch(item) {
  197.    case 1:
  198.      animate();
  199.      break;
  200.    case 2:
  201.      if(!spinning) {
  202.            setAnimation(1);
  203.      } else {
  204.            setAnimation(0);
  205.      }
  206.      break;
  207. #ifdef GL_MULTISAMPLE_SGIS
  208.    case 3:
  209.      if(glIsEnabled(GL_MULTISAMPLE_SGIS)) {
  210.        glDisable(GL_MULTISAMPLE_SGIS);
  211.      } else {
  212.        glEnable(GL_MULTISAMPLE_SGIS);
  213.      }
  214.      glutPostRedisplay();
  215.      break;
  216. #endif
  217.    }
  218. }
  219.  
  220. void
  221. vis(int visible)
  222. {
  223.   if (visible == GLUT_VISIBLE) {
  224.     if (spinning)
  225.       glutIdleFunc(animate);
  226.   } else {
  227.     if (spinning)
  228.       glutIdleFunc(NULL);
  229.   }
  230. }
  231.  
  232. /* ARGSUSED */
  233. void
  234. mouse(int button, int state, int x, int y)
  235. {
  236.   if (button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) {
  237.     setAnimation(0);
  238.     moving = 1;
  239.     begin = x;
  240.   }
  241.   if (button == GLUT_LEFT_BUTTON && state == GLUT_UP) {
  242.     moving = 0;
  243.     glutPostRedisplay();
  244.   }
  245. }
  246.  
  247. /* ARGSUSED */
  248. void
  249. motion(int x, int y)
  250. {
  251.   if (moving) {
  252.     angle = angle + .01 * (x - begin);
  253.     begin = x;
  254.     updateModels();
  255.   }
  256. }
  257.  
  258. int
  259. main(int argc, char **argv)
  260. {
  261.   glutInit(&argc, argv);
  262.   glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE);
  263.  
  264.   SoDB::init();
  265.  
  266.   if(duckScene()) {
  267.     fprintf(stderr, "couldn't read IV file\n");
  268.     exit(1);
  269.   }
  270.   glutInitWindowSize(W, H);
  271.   glutCreateWindow("GLUT Inventor Duck Pond");
  272.   glutDisplayFunc(redraw);
  273.   glutReshapeFunc(reshape);
  274.   glutCreateMenu(menuSelect);
  275.   glutAddMenuEntry("Step", 1);
  276.   glutAddMenuEntry("Toggle animation", 2);
  277.   if(glutGet(GLUT_WINDOW_NUM_SAMPLES) > 0) {
  278.       glutAddMenuEntry("Toggle multisampling", 3);
  279.   }
  280.   glutAttachMenu(GLUT_RIGHT_BUTTON);
  281.   glutKeyboardFunc(keyboard);
  282.   glutMouseFunc(mouse);
  283.   glutMotionFunc(motion);
  284.   glutVisibilityFunc(vis);
  285.   glEnable(GL_DEPTH_TEST);
  286.   glClearColor(0.132, 0.542, 0.132, 1.0);
  287.  
  288.   glutMainLoop();
  289.   return 0;             /* ANSI C requires main to return int. */
  290. }
  291.